﻿using DFGK_WMS.IRepository;
using DFGK_WMS.WebAPI.Controllers.Result;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.Linq;
using System.Net;
using System.Text;

namespace DFGK_WMS.WebAPI.Controllers.数据查询
{
    /// <summary>
    /// 数据查询
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class DataQueryController : ControllerBase
    {
        private readonly ITCellRepository tCell;
        private readonly ITReceivingOrderDetailRepository tROD;
        private readonly ITShippingOrderDetailRepository tSOD;
        private readonly ITLogRepository tLog;
        private readonly ITInstructRepository tInstruct;
        private readonly ITInventoryDetailRepository tInventory;
        private readonly ITInterfaceLogRepository tinter;
        public DataQueryController(ITCellRepository tCell, ITReceivingOrderDetailRepository tROD, ITShippingOrderDetailRepository tSOD,ITLogRepository tLog,ITInstructRepository tInstruct,ITInventoryDetailRepository tInventory, ITInterfaceLogRepository tinter)
        {
            this.tCell = tCell;
            this.tROD = tROD;
            this.tSOD = tSOD;
            this.tLog = tLog;
            this.tInstruct = tInstruct;
            this.tInventory = tInventory;
            this.tinter = tinter;
        }
        /// <summary>
        /// 货位使用率 
        /// TotalCount:总货位数 UsedCount：已使用数 UnUsedCount：未使用数 UsedRate：已使用数百分比 UnUsedRate：未使用数百分比
        /// </summary>
        [HttpGet]
        public IActionResult SOR()
        {
            int totalCount = tCell.GetAll().AsNoTracking().Count();
            int usedCount = tCell.GetAll().AsNoTracking().Where(t => t.FullStatus != 0).Count();
            return Ok(BaseResult.Result(new
            {
                TotalCount = totalCount,
                UsedCount = usedCount,
                UnUsedCount = totalCount - usedCount,
                UsedRate = Math.Truncate(usedCount * 10000.0M / totalCount) / 100,
                UnUsedRate = Math.Truncate((totalCount - usedCount) * 10000.0M / totalCount) / 100,
                XAxis = new List<string> { "已使用数", "未使用数" },
                YAxis = new List<int> { usedCount, totalCount - usedCount }
            },"200"));
        }
        /// <summary>
        /// 入库查询
        /// </summary>
        /// <param name="inboundNumber">入库单号</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult InboundStatsQuery(string? inboundNumber, int pageIndex = 1, int pageSize = 10)
        {
            if(pageIndex<=0 || pageSize<=0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            var list = tROD.GetAll().AsNoTracking();
            if (!string.IsNullOrEmpty(inboundNumber))
            {
                list = list.Where(c => c.OrderSn.Contains(inboundNumber));
            }
            var total = list.Count();
            var totalPages = (int)Math.Ceiling((double)total / pageSize);

            var results = list.OrderByDescending(x=>x.CreateDate).Skip((pageIndex - 1) * pageSize)
                              .Take(pageSize)
                              .ToList();
            return Ok(BaseResult.Result(results,"200",total));
        }
        /// <summary>
        /// 出库查询
        /// </summary>
        /// <param name="outboundNumber">出库单</param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult OutboundStats(string? outboundNumber, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            var list = tSOD.GetAll().AsNoTracking();
            if (!string.IsNullOrEmpty(outboundNumber))
            {
                list = list.Where(c => c.OrderSn.Contains(outboundNumber));
            }
            var total = list.Count();
            var totalPages = (int)Math.Ceiling((double)total / pageSize);

            var results =list.OrderByDescending(x=>x.CreateDate).Skip((pageIndex - 1) * pageSize)
                              .Take(pageSize)
                              .ToList();
            return Ok(BaseResult.Result(results, "200", totalPages));
        }
        /// <summary>
        /// 日志查询
        /// </summary>
        /// <param name="actionType">
        /// 操作类型:
        /// 0-其他；1-登录；2-退出；3-访问；4-新增；5-删除；6-修改；7-提交；8-审核通过；9-审核拒绝；
        /// </param>
        /// <param name="logDesc">日志描述</param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult LogQuery(int? actionType, string? logDesc, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            var list = tLog.GetAll().AsNoTracking();
            if (actionType.HasValue)
            {
                list = list.Where(c=>c.ActionType==actionType);
            }
            if (!string.IsNullOrEmpty(logDesc))
            {
                list = list.Where(c => c.Description.Contains(logDesc));
            }
            var total = list.Count();
            var totalPages = (int)Math.Ceiling((double)total / pageSize);

            var results = list.OrderByDescending(x=>x.CreateDate).Skip((pageIndex - 1) * pageSize)
                              .Take(pageSize)
                              .Select(c => new
                              {
                                  c.Id, c.Ipaddress, c.CreateDate, c.UserName, c.Status, c.UserRemark, c.Description, c.IpAddressName, c.LogType, c.RecordId, c.ModuleName, c.RealName, c.RecordType,
                                  actionType = ActionTypeByKey(c.ActionType.Value)
                              })
                              .ToList();
            return Ok(BaseResult.Result(results, "200", total));
        }
        private static object ActionTypeByKey(int actionTypeKey)
        {
            object result = null;
            result = actionTypeKey switch
            {
                0 => new { key = actionTypeKey, value = "其他" },
                1 => new { key = actionTypeKey, value = "登录" },
                2 => new { key = actionTypeKey, value = "退出" },
                3 => new { key = actionTypeKey, value = "访问" },
                4 => new { key = actionTypeKey, value = "新增" },
                5 => new { key = actionTypeKey, value = "删除" },
                6 => new { key = actionTypeKey, value = "修改" },
                7 => new { key = actionTypeKey, value = "提交" },
                8 => new { key = actionTypeKey, value = "审核通过" },
                9 => new { key = actionTypeKey, value = "审核拒绝" },
                _ => new { key = -1, value = "系统错误" },
            };
            return result;
        }
        /// <summary>
        /// 接口日志删除
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult DelTInter(int uid)
        {
            if(uid<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            ApiResult apiresult = new ApiResult();
            bool IsOK = tinter.DelTInter(uid);
            if (IsOK)
            {
                apiresult.code = "200";
                apiresult.message = "删除成功!";
                apiresult.data = true;
                return Ok(apiresult);
            }
            apiresult.code = "500";
            apiresult.message = "删除失败!";
            apiresult.data = true;
            return Ok(apiresult);
        }
        /// <summary>
        /// 接口日志
        /// </summary>
        /// <param name="logid"></param>
        /// <param name="staid"></param>
        /// <param name="jname"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTInterfaceLogList(int? logid, int? staid, string? jname, int pageIndex=1, int pageSize=3)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            ApiResult apiresult = new ApiResult();
            int totalCount;
            var list = tinter.GetTInterfaceLogList(logid, staid, jname, pageIndex, pageSize, out totalCount);
            if (list != null)
            {
                apiresult.code = "200";
                apiresult.message = "获取成功!";
                apiresult.data = list;
                apiresult.count = totalCount;
                return Ok(apiresult);
            }
            apiresult.code = "500";
            apiresult.message = "获取失败!";
            apiresult.data = true;
            return Ok(apiresult);
        }
        /// <summary>
        /// 重新调用
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> ReExecInterface(int id)
        {
            if(id<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            var obj = tinter.GetAll().Where(s => s.Id == id).FirstOrDefault();
            if (obj == null)
                return Ok(BaseResult.Result(false,"没有该数据","500"));
            if (obj.CallWay == null)
                return Ok(BaseResult.Result(false, "请求方式为空", "500"));

            HttpResponseMessage httpRes=new HttpResponseMessage();
            HttpClient httpClient = new HttpClient();
            if (obj.CallWay == 1)
            {
                //不清楚get请求的参数
                httpRes = await httpClient.GetAsync("http://localhost:5047" + obj.Url);
            }
            else if (obj.CallWay == 2)
            {
                //将参数转换为json格式
                HttpContent content = new StringContent(obj.InParam, Encoding.UTF8, "application/json");
                httpRes = await httpClient.PostAsync("http://localhost:5047" + obj.Url, content);
            }

            // 判断HTTP响应结果
            if (httpRes.IsSuccessStatusCode)  // 判断是否成功返回（状态码在200-299范围内）
            {
                // 处理成功响应
                string responseContent = await httpRes.Content.ReadAsStringAsync();
                // TODO: 处理响应内容
                return Ok(BaseResult.Result(true,"调用成功","200"));
            }
            else
            {
                // 处理错误响应
                HttpStatusCode statusCode = httpRes.StatusCode;
                // TODO: 根据状态码进行相应的处理
                return Ok(BaseResult.Result(true, "调用失败,系统错误", "500"));
            }

        }

        /// <summary>
        /// 指令管理
        /// </summary>
        /// <param name="InstructType">指令类型</param>
        /// <param name="Status">指令状态</param>
        /// <param name="PalletBarcode">垛号</param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTInstructPage(int? InstructType,int? Status, string? PalletBarcode, int pageIndex=1,int pageSize=10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            var list = tInstruct.GetTInstructPage(out var totalCount, InstructType, Status, PalletBarcode, pageIndex,pageSize);
            return Ok(BaseResult.Result(list,"200",totalCount));
        }
        /// <summary>
        /// 删除指令
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult DelTInstruct(int id)
        {
            if(id<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            try
            {
                if (tInstruct.DelTInstruct(id))
                    return Ok(BaseResult.Result(true,"删除成功","200"));
                return Ok(BaseResult.Result(false, "删除失败", "500"));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return Ok(BaseResult.Result(false, ex.Message, "500"));
            }
        }
        /// <summary>
        /// 指令——货品明细
        /// </summary>
        /// <param name="PalletBarcode"></param>
        /// <param name="Barcode"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetInventoryDetailPageByPalletPackageBarcode(string PalletBarcode, string? PackageBarcode, int pageIndex=1, int pageSize=10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            var list = tInventory.GetInventoryDetailPageByPalletPackageBarcode(out var totalCount, PalletBarcode, PackageBarcode, pageIndex, pageSize);
            return Ok(BaseResult.Result(list, "200", totalCount));
        }
        /// <summary>
        /// 强制完成
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UpdStatus(int id)
        {
            if(id<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            var res = tInstruct.UpdStatus(id, out var msg);
            try
            {
                if (res)
                    return Ok(BaseResult.Result(true, "成功", "200"));
                return Ok(BaseResult.Result(false, msg, "500"));
            }
            catch (Exception ex)
            {
                return Ok(BaseResult.Result(false, "系统错误", "500"));
            }
            
        }
        /// <summary>
        /// 重发指令
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ReSendInstruct(int id)
        {
            if(id<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            //找出要发送的指令
            var instructIsNull = tInstruct.GetAll().AsNoTracking().Where(s=>s.Id==id);
            if (instructIsNull.Count() <= 0)
                return Ok(BaseResult.Result(false,"未找到该条数据，参数错误","500"));

            var resInstruct=instructIsNull.First();
            //给wcs发送指令

            return Ok();
        }
    }
}
